--package.path = package.path..";?.lua"

package.path = "./plugin/BMS/utils.lua"..";..\\?.lua"
package.path = "./plugin/BMS/json.lua"..";..\\?.lua"

require ("utils")
require ("json")

MBId = 0

--rxBuf = {}
regAddr = 0

function NewVariables()
    -- body
    local VariableMap = {
        Variable = {
        },
    }

    return VariableMap
end

function GenerateGetRealVariables(sAddr,step)
    
    -- body
    local requestADU = {}
    local requestPDU = {}
    local VariableMap = {
        Status = "0",
        Variable = {},
    }

    if(step == 0)   --读保持寄存器
    then
        requestADU[1] = math.modf(MBId/256)   --事务处理标识符
        requestADU[2] = math.modf(MBId%256)
        requestADU[3] = 0x00                  --协议标识符
        requestADU[4] = 0x00
        requestADU[5] = 0x00                  --PDU数据长度
        requestADU[6] = 0x06
        ---------------------------
        requestPDU[1] = math.modf(tonumber(sAddr)%256)
        RegAddr = 62700
        RedCnt = 1
        requestPDU[2] = 0x03
        requestPDU[3] = math.modf(RegAddr/256)
        requestPDU[4] = math.modf(RegAddr%256)
        requestPDU[5] = math.modf(RedCnt/256)
        requestPDU[6] = math.modf(RedCnt%256)
        local y = 7
        for i=1,6,1 do
            requestADU[y] = requestPDU[i]
            y = y + 1
        end

        regAddr = RegAddr

        VariableMap = {
            Status = "0",
            Variable = requestADU
        }

        MBId = MBId + 1
    end

    return VariableMap
end

function DeviceCustomCmd(sAddr,cmdName,cmdParam,step)
    
    -- body
    local requestPDU = {}
    local requestADU = {}
    local VariableMap = {
        Status = "0",
        Variable = {},
    }

    if(cmdName == "GetRealVariables")
    then
        if(step == 0)   --读保持寄存器
        then
            requestADU[1] = math.modf(MBId/256)   --事务处理标识符
            requestADU[2] = math.modf(MBId%256)
            requestADU[3] = 0x00                  --协议标识符
            requestADU[4] = 0x00
            requestADU[5] = 0x00                  --PDU数据长度
            requestADU[6] = 0x06
            ---------------------------
            requestPDU[1] = math.modf(tonumber(sAddr)%256)
            RegAddr = 62700
            RedCnt = 1
            requestPDU[2] = 0x03
            requestPDU[3] = math.modf(RegAddr/256)
            requestPDU[4] = math.modf(RegAddr%256)
            requestPDU[5] = math.modf(RedCnt/256)
            requestPDU[6] = math.modf(RedCnt%256)
            local y = 7
            for i=1,6,1 do
                requestADU[y] = requestPDU[i]
                y = y + 1
            end

            regAddr = RegAddr

            VariableMap = {
                Status = "0",
                Variable = requestADU
            }

            MBId = MBId + 1
        end
    elseif(cmdName == "SetVariables")
    then
        res = json.jsondecode(cmdParam)

        if(res["ModeSet"] ~= nil)--模式设定
        then
            requestADU[1] = math.modf(MBId/256)   --事务处理标识符
            requestADU[2] = math.modf(MBId%256)
            requestADU[3] = 0x00                  --协议标识符
            requestADU[4] = 0x00
            requestADU[5] = 0x00                  --PDU数据长度
            requestADU[6] = 6
            ---------------------------
            requestPDU[1] = math.modf(tonumber(sAddr)%256)
            RegAddr = 62700
            RedCnt = 1
            requestPDU[2] = 0x06
            requestPDU[3] = math.modf(RegAddr/256)
            requestPDU[4] = math.modf(RegAddr%256)
            if((res["ModeSet"]=="0") or (res["ModeSet"]==0))
            then
                requestPDU[5] = 0x00
                requestPDU[6] = 0x00
            else
                requestPDU[5] = 0x00
                requestPDU[6] = 0x01
            end
            local y = 7
            for i=1,6,1 do
                requestADU[y] = requestPDU[i]
                y = y + 1
            end

            regAddr = 62700

            VariableMap = {
                Status = "0",
                Variable = requestADU
            }

            MBId = MBId + 1
        elseif(res["RelayCmd"] ~= nil)
        then
            requestADU[1] = math.modf(MBId/256)   --事务处理标识符
            requestADU[2] = math.modf(MBId%256)
            requestADU[3] = 0x00                  --协议标识符
            requestADU[4] = 0x00
            requestADU[5] = 0x00                  --PDU数据长度
            requestADU[6] = 11
            ---------------------------
            requestPDU[1] = math.modf(tonumber(sAddr)%256)
            RegAddr = 62701
            RegCnt = 2
            requestPDU[2] = 0x10
            requestPDU[3] = math.modf(RegAddr/256)
            requestPDU[4] = math.modf(RegAddr%256)
            requestPDU[5] = math.modf(RegCnt/256)
            requestPDU[6] = math.modf(RegCnt%256)
            requestPDU[7] = 2*RegCnt
            if((res["RelayCmd"]=="0") or (res["RelayCmd"]==0))
            then
                requestPDU[8] = 0x00
                requestPDU[9] = 0x00
                requestPDU[10] = 0x00
                requestPDU[11] = 0x00
            else
                requestPDU[8] = 0x00
                requestPDU[9] = 0x00
                requestPDU[10] = 0x00
                requestPDU[11] = 0x00
            end
            local y = 7
            for i=1,11,1 do
                requestADU[y] = requestPDU[i]
                y = y + 1
            end

            regAddr = 62701

            VariableMap = {
                Status = "0",
                Variable = requestADU
            }

            MBId = MBId + 1
        end
    end

    return VariableMap
end

function GetVariable(pdu,pduIndex,len)

    local variable
    if(len == 1) then
        variable = pdu[pduIndex]
    elseif(len == 2) then
        variable = pdu[pduIndex]*256+pdu[pduIndex+1]
    elseif(len == 4) then
        variable = pdu[pduIndex]*16777216+pdu[pduIndex+1]*65536+pdu[pduIndex+2]*256+pdu[pduIndex+3]
    elseif(len == 8) then
        local variableHigh = pdu[pduIndex]*16777216+pdu[pduIndex+1]*65536+pdu[pduIndex+2]*256+pdu[pduIndex+3]
        local variableLow = pdu[pduIndex+4]*16777216+pdu[pduIndex+5]*65536+pdu[pduIndex+6]*256+pdu[pduIndex+7]
        variable = variableHigh*16777216 + variableLow
    end


    return variable
end

function AnalysisRx(sAddr,rxBufCnt)

    local mID = 0
    local mProtocal = 0
    local mPDULen = 0
    local mAddr = 0
    local mFunCode = 0
    local mRegByte = 0

    -- body
    local VariableMap = {
        Status = "1",
        Variable = {},
    }

    --modbus 必要元素8个字节
    if(rxBufCnt < 8)
    then
        rxBuf = {}
        return VariableMap
    end


    for index=1,rxBufCnt,1 do
        if(index <= rxBufCnt)
        then
            mID       = rxBuf[index]*256+rxBuf[index+1]   --事务处理标识
            mProtocal = rxBuf[index+2]*256+rxBuf[index+3] --协议标识符
            mPDULen  = rxBuf[index+4]*256+rxBuf[index+5]  --PDU长度
            mAddr     = rxBuf[index+6]                    --设备地址
            mFunCode  = rxBuf[index+7]                    --功能码
            print("mPDULen "..string.format("%d",mPDULen))
            print("mAddr "..string.format("%d",mAddr))
            print("mFunCode "..string.format("%d",mFunCode))
            if(mAddr == tonumber(sAddr))
            then
                if(mFunCode == 0x01)
                then
                    if(rxBufCnt-7-index <= 0) then
                        print("数据长度不够，没有数据长度")
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                        rxBuf = {}
                        return VariableMap
                    end
                    mRegByte = rxBuf[index+8]
                    if(rxBufCnt-7-index-mRegByte <= 0) then
                        print("数据长度不够，没有数据域")
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                        rxBuf = {}
                        return VariableMap
                    end
                    --取出数据域数据
                    local pdu = {}
                    local pduIndex = 1
                    for i=index+9,index+9+mRegByte,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu,rxBuf[i])
                        end
                    end
                    local Variable = {}
                    local VariableIndex = 1
                    if(regAddr == 1) then
                        if(pdu[pduIndex] == nil) then
                            rxBuf = {}
                            return VariableMap
                        end
                        local coilValue = pdu[pduIndex]
                        pduIndex = pduIndex + 1

                        VariableMap = {
                            Status = "0",
                            Variable = Variable
                        }
                    else
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                    end
                    rxBuf = {}
                    return VariableMap
                elseif((mFunCode==0x03) or (mFunCode == 0x04))
                then
                    if(rxBufCnt-7-index <= 0) then
                        print("数据长度不够，没有数据长度")
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                        rxBuf = {}
                        return VariableMap
                    end
                    mRegByte = rxBuf[index+8]
                    if(rxBufCnt-7-index-mRegByte <= 0) then
                        print("数据长度不够，没有数据域")
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                        rxBuf = {}
                        return VariableMap
                    end
                    --取出数据域数据
                    local pdu = {}
                    local pduIndex = 1
                    for i=index+9,index+8+mRegByte,1 do
                        if rxBuf[i] ~= nil then
                            table.insert(pdu,rxBuf[i])
                        end
                    end
                    local Variable = {}
                    local VariableIndex = 1
                    if(regAddr == 62700) then
                        --------------------------控制模式------------------------------------------------
                        local ModeSet = pdu[pduIndex]
                        pduIndex = pduIndex + 2
                        Variable[VariableIndex] = utils.AppendVariable(VariableIndex,"ModeSet",ModeSet,ModeSet)
                        VariableIndex = VariableIndex + 1

                        VariableMap = {
                            Status = "0",
                            Variable = Variable
                        }
                    else
                        VariableMap = {
                            Status = "1",
                            Variable = Variable
                        }
                    end
                    rxBuf = {}
                    return VariableMap
                elseif((mFunCode==0x05) or (mFunCode == 0x06))
                then
                    VariableMap = {
                        Status = "0",
                        Variable = Variable
                    }
                    rxBuf = {}
                    return VariableMap
                elseif((mFunCode==0x81) or (mFunCode==0x82) or (mFunCode==0x83) or (mFunCode==0x84))
                then    
                    VariableMap = {
                        Status = "1",
                        Variable = Variable
                    }
                    rxBuf = {}
                    return VariableMap
                else
                    index = index + 1
                end
            else 
                index = index + 1
            end
        end
    end

    rxBuf = {}
    return VariableMap
end

--rxBuf = {0xb1,0x93,0x00,0x00,0x00,0x09,0x02,0x03,0x06,0x00,0x01,0x00,0x04,0x01,0x04}
--rxBuf = {0xb1,0x93,0x00,0x00,0x00,0x09,0x02,0x03,0x06,0x00,0x01,0x00,0x04,0x01,0x04}
--rxBuf = {0xb1,0x8f,0x00,0x00,0x00,0x04,0x01,0x01,0x01}
--State = 2
--AnalysisRx(1,10)